/**
 * @description:
 * @file: export-file.ts
 * @author: Evan
 * @date: 2025.04.23 18:00:02
 * @week: 周三
 * @version: V
 * */

import { saveAs } from 'file-saver'
import * as XLSX from 'xlsx'
import { getFormatDate } from './date'

/**
 * 导出表格
 * @param el dom 容器
 * @param options 选项
 * @param options.columnWidths 用列名（表头名）指定宽度
 * @param options.defaultWidth 可自定义默认宽度（默认15）
 * @returns
 * @example
 * 示例:1
 * exportTable(tableElement); // 所有列宽15
 * 示例:2
 * exportTable(tableElement, {
 *   columnWidths: {
 *     '姓名': 10,
 *     '年龄': 10,
 * }
 * })
 * // 导出表格到当前日期时间的Excel文件
 * // 列宽：姓名10，年龄10，其余默认15
 * 示例:3
 * exportTable(tableElement, {
 *   columnWidths: {
 *     '姓名': 10,
 *     '年龄': 10,
 *     '性别': 10,
 *     '手机号': 15,
 *     '邮箱': 20
 *   },
 *   defaultWidth: 10
 * })
 * // 导出表格到当前日期时间的Excel文件
 * // 列宽：姓名10，年龄10，性别10，手机号15，邮箱20，其余默认10
 * 示例:4
 * exportTable(tableElement, {
 *   fileName: '自定义文件名',
 * })
 * // 导出表格 自定义文件名.xlsx
 * 列宽默认15
 */

export const exportTable = (
  el: HTMLElement,
  options?: {
    fileName?: string // 导出文件名
    columnWidths?: Record<string, number> // 用列名（表头名）指定宽度
    defaultWidth?: number // 可自定义默认宽度（默认15）
  }
) => {
  const workbook = XLSX.utils.table_to_book(el)
  const ws = workbook.Sheets[workbook.SheetNames[0]]
  const wsRef = ws['!ref'] || ''
  const range = XLSX.utils.decode_range(wsRef)

  // 获取表头行（假设表头在第一行）
  const headerRow = XLSX.utils.sheet_to_json<string[]>(ws, { header: 1 })[0]

  // 默认宽度（可自定义）
  const defaultWidth = options?.defaultWidth ?? 15

  // 初始化列宽数组
  ws['!cols'] = ws['!cols'] || []

  // 遍历所有列，设置列宽
  for (let C = range.s.c; C <= range.e.c; C++) {
    const columnName = headerRow[C] // 获取当前列的表头名
    const customWidth = options?.columnWidths?.[columnName] // 查找是否传入了该列的宽度

    // 使用传入的宽度（如果有），否则用默认宽度
    ws['!cols'][C] = { wch: customWidth ?? defaultWidth }
  }

  // 生成并下载Excel
  const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' })
  const excelData = new Blob([excelBuffer], { type: 'application/octet-stream' })
  const name = options?.fileName || getFormatDate(0, 'yyyy-MM-dd-hh_mm_ss')
  saveAs(excelData, `${name}.xlsx`)
}
